Maps: adding more (related) sObjects than key values using PUTALL method

PutAll only works on the ID field of an SObject. It is syntatic sugar for:

for(SObject record: someList)
    someMap.put(record.Id, record);

To use any other type of mapping, you would have to make your own for loop.

Such a for loop would look like:

Map<Id, Contract[0]> someMap = new Map<id, contract[0]>();

... load account ids here ...

for(Contract record: [SELECT Id, AccountId, random_field FROM Contract WHERE AccountId IN :someMap.keyset()]) {
    if(someMap.get(record.AccountId) == null) {
        someMap.put(record.AccountId, new Contract[0]);
    }
    someMap.get(record.AccountId).add(record);
}

In your specific case, I might consider using a subquery:

someMap.putAll([SELECT Id, (SELECT Id, random_field FROM Contracts) FROM Account WHERE Id IN :someMap.keySet()]);

You can access a list of contracts via:

for(Contract record: someMap.get(accountId).Contracts) ...

So, basically, you would like to have a map of key-value pairs, where key is the AccountID, and the value is list of Contracts related to the Account? If so, first of all, rather than having Map < id, contract >, what you are really looking is Map < id, List < Contract > >.

Further on, you could store the list of id's - in the list. And only then use the list of ids to query the contracts and populate the map:

map<id, contract> accIDtoContract = new map<id, List<contract>>();

List<id> accIDs = new List<id>();
for( Usage_Data__c UD : Usage_Data_List ){
    // Don't store AccountID in the list if it was already stored
    if(accIDs.contains(UD.Account__c))
        continue;

    accIDs.add(UD.Account__c);                      
    accIDtoContract(UD.Account__c, new List<Contract>());
}

List<contract> contracts = [SELECT ID, AccountID, random_field FROM Contract WHERE AccountID IN :accIDs]);

for(Contract c : contracts) {
    accIDtoContract.get(c.AccountID).add(c);
}