By default all memory addresses are within DS. Exceptions are the destination addresses of STOSx/MOVSx and CMPSx where ES is used (*1). DS can be replaced by any other segment register in all instructions (and ES in STOSx) by adding a segment override prefix.
So with the exception of ES when it comes to string destination segment any Segment can be used at cost of an additional instruction byte. Which segment register to be used when leaving the default is rather arbitary.
The introduction of FS/GS eased the need to reload segment registers.
Adding one segment (FS) eased A=B+C type operations where each of the components resides in a seperate segment, like when doing large amounts of data (tables), without constant reloading of segment registers. After all, each load needs not only to load all segment information, but also runs neccessary priveledge checks.
Adding a two (FS&GS) even removed that restriction, allowing a program to hold three arbitary data segments in addition to Code, Programm Data and Stack.
Fire at Will
*1 - And then there are all addressing modes with BP and SP,as they are calculated with SS as base value - after all, BP is the stack frame pointer.