What is the best way to copy/append geometry from one bmesh to another
Your bmesh is just a python representation of the mesh thats in your scene. As long as you don't write your bmesh back into the mesh-datablock (bm.to_mesh(me)), you can use it for anything you want to do with it.

This means you can create a new mesh datablock and then use 

bm.to_mesh(new_mesh)

since it's just a python object, you can copy it with a python copy method:

bm2 = bm.copy()

Which will give you a fully editable bmesh that is disconnected from your first bmesh. So you don't have to copy every vert &amp; edge manually.

edit: this is how you seperate the mesh into two halfs that were split. You can then write it back into the edit mesh and separate the loose parts which will give you two objects. Because with your current code you get vertices and edges that define where your mesh is being cut, and not the actual geometry. -> your result:



My code example:

import bpy
import bmesh

bm_tmp = bmesh.new()
bmesh.ops.create_monkey(bm_tmp)

geom = bm_tmp.verts[:] + bm_tmp.edges[:] + bm_tmp.faces[:]
r = bmesh.ops.bisect_plane(bm_tmp, geom=geom, 
    plane_co=(0, 0, 0), plane_no=(0, 0, 1))

bmesh.ops.split_edges(bm_tmp, edges=[e for e in r['geom_cut'] if isinstance(e, bmesh.types.BMEdge)])

bm_tmp.to_mesh(bpy.context.selected_objects[0].data)
bpy.ops.mesh.separate(type='LOOSE')


Visual result from this code:


Edit 2:
in that case, that you want to slice it multiple times -
instead of writing it to a new bmesh after each bisect, do this:

bmesh.ops.split_edges(bm_tmp, edges=[e for e in r['geom_cut'] if isinstance(e, bmesh.types.BMEdge)]) 

to apply the bisection to your bmesh and actually separating it by parts.
In the end you can write it to a actual mesh. Only then i would combine it with your other bmesh. You can't simply add two bmesh together.
so i'd suggest combining them like this, because it is the simplest way:

bm = bmesh.new()

bm.from_mesh( m1 ) # Add mesh 1 to bmesh
bm.from_mesh( m2 ) # Add mesh 2 to bmesh