We use a range of tools, depending on the kind of leak, and where it is located.
Lua is a garbage collected language that can't truly leak memory (the Lua VM tracks all object allocations and cleans up anything that is finished with), but sometimes a bug can accidentally cause data to be kept around longer than intended. For debugging this kind of leak, we use a diagnostic tool we built that dumps the Lua state to a file which can be inspected in various ways.
Lua integrates with C, which is not a language with garbage collection. A number of the libraries that Prosody depends on are written in C, and are obvious candidates for leaks. Luckily there are many existing tools for catching these, such as valgrind.
Finally there is a third kind of leak, which is caused by a combination of memory allocation patterns and the memory allocator that is in use, this is known as memory fragmentation. This can cause the process to appear to the OS that is is using more memory than it really using internally.
After investigating a range of deployments, we've not found any leaks tied to the Prosody codebase. We did identify a small leak in a third-party library (LuaSec), but this is unlikely to affect Jitsi deployments that don't federate.
Most of our current analysis points to the third cause being the most common issue. Unfortunately it's potentially one of the hardest for us to fix, since allocation patterns are largely controlled by the Lua VM and the garbage collector.
As part of this work we recently adapted our trunk nightly packages to run on any Lua version (5.1, 5.2, 5.3, soon 5.4). Each Lua version has received changes to its algorithms, and each one has different configuration options that control the GC and alter allocation patterns. This will allow us to perform more experiments and gather more data about what may reduce fragmentation for affected deployments.
Another parallel solution is experimenting with different memory allocators. In the past I demonstrated that jemalloc significantly reduced fragmentation in earlier versions of Prosody. If we can reproduce that result, we may look at making it easier (or the default) to run Prosody with jemalloc. I'm not going to provide instructions here as the internet is likely full of them, but actually testing jemalloc is something anyone can do with no code changes and just a bit of sysadmin skills.