For an emulator to be "cycle accurate" means the interactions between the components are timed accurately enough so that the emulation behaves the same way as the original machine for any given input. I mean "input" in the general sense -- both external inputs such as keyboards, joysticks, buttons, etc. and the program (or programs) being run, the data available on devices and so on.

Early (late 1970s to early 1980s) game consoles and home computers almost always ran off a single base clock frequency that was divided down by various factors to run the main CPU, graphics, sound and other systems. In those cases a cycle would refer to the highest clock frequency which is typically that provided to the graphics system. So, for example, there was often an exact number of CPU cycles per video frame.

As you point out, for systems with multiple clocks the notion of a cycle doesn't make any real sense. But each subsystem driven by a clock will operate in fixed steps so we stretch the term "cycle accurate" to mean that each part of the system will perform its operations in the same amount of real time as the original and the interactions between each subsystem are such that they will seem the others running at the same relative speed.

For most of an emulator's operation timing accuracy is not a concern. If the CPU stores 7 into a memory location it doesn't matter exactly when it happens because the change cannot be noticed by anything else in the system. But if the processor changes a video memory location then timing may make the difference between the video output changing or not.

The other side of cycle accuracy is duration. If the emulated CPU runs faster than a real CPU (perhaps because it takes few cycles for some or all instructions) then a game may be seen to run too quickly. For the most part such timing is easy to get right and is usually made inaccurate by not modelling interactions with RAM or devices. Sometimes the CPU is slowed down a little bit when it reads/writes memory. That can be difficult to emulate correctly but without that bit of accuracy games or other applications will run too quickly. Not generally a problem for a word processor, but for games or more highly interactive applications it will be noticable to the experienced user.

Component Interactions

Except for RAM, interaction between the CPU and supporting subsystems is mostly one way. ROM only returns values as asked. Sound systems only change their output based on what the CPU tells them. Joysticks and keyboards only report user input to the CPU. Graphics only change when the CPU sends new data. BUT, only mostly.

Graphics systems can tell the CPU when a new frame has started. Sound systems might report when they have finished playing a bit of audio. Any time a component can give feedback to the CPU there may be a need for timing accuracy. But how much accuracy is required really depends on the particular device and the program's use of that device.

For instance, in a simple game the positions of various sprites (player and enemies) on screen might be updated once per frame. In that case cycle-level accuracy isn't needed. All you need is for the "start frame" indication to come by at a frequency that is close enough to the original for a human to think it exact and the CPU runs fast enough to make the change before the frame drawing begins.

More complex games might change sprite positions while the graphics display is drawing them. Typically the graphics processor will help out by giving an indication of when each line starts. Now cycle accuracy is more important. If the CPU runs a bit slower than it should the sprites will be updated too late causing them to flicker or briefly appear distorted. There isn't an intrinsic difference between this and the "once per frame technique" from an emulator perspective. It's just that the times involved are smaller and thus small timing inaccuracies can make a big difference.

Looking at that you might think that running the CPU a bit more quickly than usual might be fine. Indeed, it might. But then you run into a program which gets the "new line" signal an intentionally delays before changing the sprites. This works because the the hardware only looks at new sprite values at the start of the line. If the changes happen while the line is drawing the changes won't show up until the next line which is what the program expects. Unless you want to program your emulator to have special cases for each game (a viable but time consuming strategy) you learn that your best bet is to be "cycle accurate" so that these different things all work properly.

And there can be even more extreme cases. Some graphics hardware only gives the "new frame" indication. But sprites can be changed on a per-line basis. Very clever programmers will use the "new frame" signal then go into a CPU delay loop precisely timed to wait until, say, half-way down the screen where they'll update the sprites. That's only going to work if the relative timing of the CPU and graphics is exact and the count of cycles per instruction is perfect.

The point being that component interactions can happen because of explicit feedback (e.g., the graphics saying a new line has started) or because of implicit knowledge (e.g., the CPU knows exactly what portion of the display is being shown because it can mark time).