As an exercise, I built this ICE tree that prevents any overlapping particles (for non-rotated particles only). It works by comparing the X, Y, and Z values of the vector between two points with the combined size of the two particle shapes (which are boxes in this example).
The compound node returns an array of booleans, one for each neighbour. The boolean flags indicate whether or not the particles would overlap, so if at least one is True, then I delete the particle. If you must see it, here’s the compound: