To change the label positions for a given plot manually you can use the following syntax by providing the annotations coordinates:
scatter(df.x1, df.x2; annotation = (x, y, text.(df.city, :magenta, 6)), leg=false)
Just change x, y around df.x1, df.x2, with the required offsets.
The general problem is very difficult. It would be easier to abbreviate the city names to 2 or 3 letters max and annotate randomly around the points. See this other thread.