Yeah dozens of things, the docs cover many. I should note though that outside of homebrew programming most old consoles were all included in the binary so no filesystem or executable layout of great note happened. Exceptions for things that were basically computers (amiga and things that came on floppy discs) and things that came on CDs. Even in those exceptions though things are not above being stuck in the binary.
Brute force starts with open in hex or tile editor and press page down a lot, it ends with you corrupting parts of the ROM, running it and then seeing what changed. You can direct your corruption as well so if you see ?? though XX is graphics then no need to corrupt that when looking for text. Many seem to discourage corruption nowadays but I am not inclined to forget it yet.
After this is recursive searching -- run the ROM, see the graphics you want loaded into memory (there is not a lot of it on the NES after all), see the segment you want and search the ROM for that. On later systems I use this to find graphics palettes quite successfully. Altered data (said palettes are fine until they are dynamic), compression, encryption and more will trouble this.
Fingerprinting. A given file format may feature a given sequence. On the GBA the ROM tends to be read using the 08000000 through 08FFFFFF memory range so I see a bunch of 08??????08ZZZZZZ08YYYYYY then I might well have a table/field/map of pointers. Neither are so useful or as readily workable on the NES where many things were custom from the ground up and the mappers using bankswitching mean not everything is visible at all times but still worth having in mind. Compression can also have tell tale signs and so you can search for it, though what limited stuff there is on the NES is often again custom from the ground up rather than provided by the SDK/BIOS like some later systems.
Things like relative search. Not so useful for Japanese text but most custom text encodings follow the Roman alphabet, a relative search tool (I like monkey moore) will then search the ROM for patterns in the phrase you feed it (CAB is one value, a value two lower than that and the final one is one less than the first). For text there are a load more, value distribution (space is probably the most common character and have you ever considered why scrabble is scored the way it is?), ROM alteration (you know some values for text but not all -- you have a hex editor and the means to run/test it...), font scanning (encodings will tend to follow the order of a font) and the list goes on.
Finally we hit the assembly methods. I already mentioned searching the ROM using data plucked from memory, that is probably the weakest method here. The king of all methods is tracing where you find the thing in memory, tell the emulator to stop when it or that area is written to and then you manually work backwards. It is hard and tedious but it will find what you want every time. There are logging features as well. Bonus is the NES features one of the finest debuggers outside of the PC, and even then it could teach IDA a thing or two, http://www.fceux.com/web/help/fceux.html?Debugger.html
There are a bunch of things the debugger can do as well. Logging is also one of those and you can do things like log all branches when playing something, then do the you want to do which you did not do before and then have it tell you what new branch it did. On later systems with those decompression routines that BIOS supports you can log all such calls to the BIOS and as it needs to know what it is decompressing you will have nice ROM addresses for it.
Anyway I appear to find myself rewriting documentation written many times before (and not from memory first thing on a Sunday morning) so I will leave it there.