Surely a duplicate but I couldn't find a good fit to link, so made a simple setup:
- Blue Frame: Random Value node to get some random positions for points, all at Z=0.
- Orange Frame: Noise Texture node differs from the above in that neighboring values are similar (Perlin Noise). This way, as time passes, the noise is sampled in a different position, so the output value changes, but doesn't change abruptly (e.g. from $0.3$ to $0.7$ in one frame), instead changes smoothly (e.g. from $0.3$ to $0.305$ in one frame). However, I don't want all points to move in a similar direction, so I increase the scale of noise to $50$ (zoom the texture out 50×). Now there's 50× more space between points, meaning there's much less consistency between them. But this means there's also much less consistency between frames, so I multiply the frame by $1‰$ (effectively the Z dimension has scale $50×0.001=0.05$, so very small changes between frames, very smooth changes between offsets = very slow movement). Multiply Add converts the range from $0..1$ to $-0.50..+0.50$, so it makes sure the displace happens in both ways, it is small, and it is none in the Z axis.
- Green Frame: Make a 50 points vertical curve and spawn it 3 times (once for each point).
- Navy Frame: This time the Noise Texture is 3D, because we're operating not on a plane, but in 3D space (each point has also a height), and we don't want neighboring points of a single curve to displace in the same direction. So to animate, we use 4th dimension. This time Multiply add produces a much bigger range, giving more freedom for the curves, making them wiggle out of their base more than their bases move around (artistic choice). Finally, the effect is scaled based on height.
You could capture curve factor and use that instead of Z (especially if you don't spawn curves on a horizontal surface), you could use new Simulation Zone to make the movement more realistic etc. but this is the basic idea.