I have seen a cache plan bloat problem like this before.
It was caused by hundreds of stored procedures implemented with passed in arguments converted to local variables, the developer's theory being that parameter sniffing was a problem, and by confounding the parameter sniffing, he was able to force recompilation of the stored procedures' query plans with every execution of the stored procedures.
His technique did improve stored procedure execution times. But the old plans remained unused in memory and the plan cache grew and grew, with many thousands of unused query plans for the same stored procedures.
To offset this problem, the developer created a SQL Agent job to execute the DBCC FREEPROCCACHE command every 4 hours, which cleared the plan cache but didn't help server performance.
I eliminated the SQL Agent job and added "WITH RECOMPILE" to all of the stored procedures. This eliminated the plan cache bloat problem.
This was not an ideal solution. The "WITH RECOMPILE" clause forced no query plan reuse and added a small amount of time to every stored procedure execution. But, the stored procedures' executions times were still shorter than without the shuffling of arguments into local variables and the plan cache bloat problem disappeared.
For this particular set of stored procedures, there was a wide variance in passed in arguments, especially for date ranges, so the developer's theory about parameter sniffing may have had some validity. Empirical results from testing seemed to confirm it.