A point cloud which is 4-way symmetrical will have 4 axes of reflectional symmetry, where each axis is offset from the next by 45 degrees. To find all axes it therefore suffices to find one.
The following home-made algorithm works pretty well at finding that axis. Trial testing of clouds with an average of 500 points gives the following statistics regarding the deviation $D$ between the axis angle found by the algorthm and the true axis angle:
Perfect cloud:
$D \lt 1^\circ$: $100$%
Cloud with 2% missing points:
$D \lt 1^\circ$: $55$%
$D \lt 2^\circ$: $90$%
$D \lt 3^\circ$: $99$%
I'll discuss problem areas at the end of the post, but first to the algorithm.
Algorithm overview
For a 4-way symmetrical cloud, at least one axis of symmetry must exist within any $45^\circ$ sector, as seen from the centroid of the cloud. At the extreme, there will be one axis at the very start of the sector and another axis at the very end of the sector. An axis of symmetry is characterised, in this case, by the fact that all points within a $45^\circ$ sector to the "left" of the axis are mirrored by the points within a $45^\circ$ sector to the "right" of the axis. A very simple (non-robust) way to check if an axis at a given angle is an axis of symmetry, is to see if the number of points in the $45^\circ$ sector to the left of the axis is equal to the number of points in the $45^\circ$ sector to the right of the axis. A better way (which this algorithm uses) is to check if the sum of the distances from the centroid to the points in the $45^\circ$ sector to the left of the axis, is equal to the sum of the distances to the points in the $45^\circ$ sector to the right of the axis.
So, the basic idea of the algorithm is to have an axis move from $91^\circ$ to $44^\circ$ in $1^\circ$ steps, calculating the sum of the distances to the points in the left sector and the sum of the distances to the right sector at each step, and comparing these sums. The angle of the axis where the sums are "most equal" is then the algorithm's axis of symmetry.
The reason for using $91^\circ$ and $44^\circ$ instead of $90^\circ$ and $45^\circ$ is to avoid rounding problems. In addition, I use sectors of $47^\circ$ (which means the left and right sector overlap) instead of sectors of $45^\circ$ to avoid problems with points which are at or close to the dividing line between the left and the right sector.
The above is obviuosly not a robust method in general, but for a cloud where 4-way symmetry is assumed, it works.
Algorithm with details
Assuming all points are in an array with Cartesian coordinates:
Find the centroid $(X_c, Y_c)$ of the cloud.
Find the polar coordinates of each point, using $(X_c, Y_c)$ as origo, and save the points which have an angle between $91 + 46 = 137$ degrees and $44 - 46 = -2$ degrees in a new array $NewA$.
Sort $NewA$ according to angle, from largest to smallest.
Run through the angles $A$ from $91^\circ$ down to $44^\circ$ in steps of $1^\circ$. At each angle, calculate the distance sum for points in the left sector (i.e. points with $ A - 1 \lt$ angle $\lt A + 46$) and compare with the distance sum for points in the right sector (i.e. points with $ A + 1 \lt$ angle $\lt A - 46$).
The angle $A$ at which this comparison is closest to one, is the algorithm's axis of symmetry angle.
Areas for improvement
The algorithm is sensitive to "error" in the coordinates of the centroid. When points are missing or displaced, the centroid is not at the ideal (correct) location.
The algorithm is also somewhat sensitive to the 2% errors if they mainly occur in the first and second quadrant (where this algorithm's input comes from).
Not sure what to do about these points.