When working in a trigger values for all fields are loaded, but not for related objects.
With the lookups to account, record type and owner (user) you get the IDs because they've been loaded as the field values, but account name, record type and owner name aren't loaded as they are fields on the related records, not on the records being worked.
To get the names you'll have to collect the IDs for each type (probably in a map) and then query for them, so for accounts you'd do something like this:
Map<Id, Account> accounts = new Map<Id, Account>();
If (describeResult.getName() == 'AccountID')
{
String AccountID = c.get(describeResult.getName())
accounts.put(AccountID, null);
}
/* Snip */
for(Account a : [select Id, Name, OtherFields from Account where Id in : accounts.keySet()])
{
accounts.put(a.Id, a.Name);
}
For your use case you'd then need to loop over the lookup fields once more to get the values.
Something To Consider
Although for history tracking purposes having the names would be easier to read, tracking the changes to the IDs would be just as valid (in fact it would potentially be the only real way of tracking history as pointed out by @ManSpan below). Assuming that you're storing this history information in a custom object, you could always a custom page that displays records take care of looking up names for IDs.