You could do a quick comparison with a Set
operation.
You could simply go:
Set<sObject> oldRecordSet = new Set<sObject>(Trigger.Old.deepClone(true, true, true));
oldRecordSet.removeAll(Trigger.New);
Integer numberOfChanges = oldRecordSet.size();
If the number is 0, there were no changes. Otherwise, you have the number of changes.
If there were changes, you can then get the Ids of the records that did change like this:
Set<Id> changedRecordIdSet = (new Map<Id, sObject>(new List<sObject>(oldRecordSet))).keySet();
I haven't tested it yet, but I believe this will work.