The problem is what you mean by “eliminate DDMs that are not used,”. I am guessing that you not only want to eliminate DDMs that do not physically exist in code, but also want to eliminate DDMs that physically exist but are never used.
The latter would be quite time consuming and tedious. It would involve, for example, first looking for the DDMs in objects as Ralph mentioned. Then, however, you would have to see if the objects are ever actually executed. Indeed, it gets worse. You could have a DDM in an object (say a subprogram) that is simply never referenced CALLNAT’ed) in the main line of a system, or a DDM in an object that is used in the code, but the logic of the DDM in the object is such that the code that uses the DDM will never be executed.