To be honest, I find listing files to be almost completely useless. They tell me what I already knew - namely what I just wrote. I find a disassembly much more informative. But other people find listing files very valuable, so perhaps it's just me. Maybe somebody who actually uses the things will have a better answer for you.
Listing files are sometimes useful in debugging macros - simply to assert that the correct output is generated, and if that isn't the case, then to find the line of a macro that created the wrong output (or that failed to output anything). They're useful for learning some other stuff as well, such as, what instruction form NASM generated, how long it is, etc. These are all useful even if you ain't debugging NASM. In large programs, it is usually easier to locate the instruction or macro output in the listing file than it would be to disassemble/debug the entire executable or object file. In case of instructions, you can still enter the bytes in the listing into a debugger faster than searching for the instruction. (Of course, relocations are not applied in the listing so sometimes you have to debug a program to get it right.)
Unfortunately listing is somewhat limited, in that the source code it shows is only partly preprocessed. An option to make it show the fully preprocessed source, including single- and multi-line macro expansions as well as the full name of macro-local, context-local and local labels, and omitting comments and code in conditional branches that are disabled, would be more useful for some things. Even though you can surely achieve some of this with regexes, as I was advised on a similar feature request, things like macro and label expansion and processing of preprocessor conditionals you can't achieve with them.
And just in case you think running the preprocessor on a file first, then assembling it to achieve a listing similar to what I described is an option: It isn't. The preprocessing-only mode does not currently support any preprocessor directives (mostly expressions in conditional directives and %assign) which reference $ or $$ so it is unable to process even the most basic TSRs I write. (Possible support for that could be achieved by not omitting the affected %assigns and conditional constructs - this would then require the output to be preprocessed while assembling though.)