I don't think there is any easy way to do this. Here are a few ways, however they are quite resource intensive:
Remesh modifier:
You can use the Remesh modifier to do this, however it will take a long time to compute and result in a very dense mesh.
Make sure you have Remove Disconnected Pieces disabled:
Python:
Expanding on Matt's answer, you can make a script that will create boolean modifiers for every cube on every cube:
import bpy
# Make a group of your particle cubes and replace 'Group' with the name of your group:
particles = bpy.data.groups['Group'].objects
#iterate through every cube in the group:
for object in particles:
# Remove all existing modifiers:
object.modifiers.clear()
# For every object in the group,
for target in particles:
# Test if the object is the not the same as the object we are currently adding modifiers to:
if target.name != object.name:
# Add a boolean modifier
mod = object.modifiers.new(name="test", type="BOOLEAN")
# Set the target object:
mod.object = target
# Set the operation mode to UNION:
mod.operation = 'UNION'
I tested it with 100 cubes and it took quite a long time.
Also note that every cube will be joined to every other cube, so there will be a lot of failed boolean operations caused by cubes that don't intersect trying to be joined.
P
> Loose Parts) and use boolean modifiers, however I don't think there is any easy way to set this up for so many objects. You might be able to script it, but I can't think of how the script would detect which cubes need to be boolean intersected with which cubes. You would need to somehow get the names of the cubes which are intersecting a given cube. $\endgroup$