I don't know a book on this topic, although there may well be one. I don't think one would be necessary, however. As I understand it, there's no magic to this process, just an approach that involves pushing as much of the functionality out of hard-coded systems and into data.
Components, eg. the Bilas approach in Dungeon Siege, are one good way of doing this because you specify which components to use in the data. There are 101 ways of implementing game components however and not much agreement between them. Currently I think the best way is to just write something that works for you.
Scripting is another way - although technically it's still 'code', it's also 'data' in that the script files are parsed at run-time by the program, and again you can change behaviour without necessarily even restarting the program.
Pushing all of your constants out to an INI or XML file is another angle. That way designers can tweak fundamental parts of the game engine without needing coders to make alterations.
Continuing along those lines, some sort of property pattern is useful for defining hierarchies in data rather than code. Reading entity properties from data and allowing some sort of inheritance between different lists of properties gives you a lot of scope to define much of the game without touching the code or needing recompilation, at the expense of type safety etc. (The canonical link is here although that overstates the point somewhat.)