The solution is based on customized ELResolver. We know that backing beans are bound to the view(jsf pages) using Expression Language(EL). ELResolver actually resolves thesa 'binding expressions' at runtime. So idea is to intercept in the invocation of setters for the backing beans through a customized ELResolver. And add the logic to track the modified attributes at this point. JSF specification enables to add customized javax.el.ELResolver by modifying faces-config.xml.
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee">
Now we can hook the custom logic to address the above requirement by overriding the ELResolver::setValue(...). Adding this logic is left to you, needless to say your backing bean may need to follow predefined contract to enable the centralized processing at ELResolver. What I meant is, bean may need to implement a predefined interface and the ELResolver can work on the 'instance of' this specific object type.
You can download the sample workspace from here.