Static analysis is your friend here. TypeScript, Rust, and C# can all identify dead code and report errors or warnings from that, and can perform "find all usage" searches across a workspace.
Python's cold acceptance is already enough to make big projects impractical on it, because every large codebase will gather some undecidable metaprogramming spread through it. But Ruby gets it everywhere.
Metaprogramming: the cause of, and solution to, all of life's problems.
No matter how many times you say it, that doesn't make it true.
It doesn't help with potentially reachable but unused cpdepaths, which in my experience make up for the most of 'dead' code.
Think of the functionality in an application that nobody uses or of obsolete API version when all the clients use a more recent version.
30-15 to static analysis, I think? ;)