you can find an example in the open source code of las2las.cpp as this becomes necessary whenever reprojecting from one CRS to another. Below the distilled rundown that should work (minus whatever bugs this untested pseudo code has).
// create new header for output
LASheader header = lasreader->header;
// zero the pointers of the old header so they don't get deallocated twice
lasreader->header.unlink();
// transform the center of bounding box to new position
F64 point[3];
point[0] = (header.min_x + header.max_x)/2;
point[1] = (header.min_y + header.max_y)/2;
point[2] = (header.min_z + header.max_z)/2;;
transform(point, point);
// use position to create better suited offsets
header.x_offset = ((I64)((point[0]/header.x_scale_factor)/10000000))*10000000*header.x_scale_factor;
header.y_offset = ((I64)((point[1]/header.y_scale_factor)/10000000))*10000000*header.y_scale_factor;
header.z_offset = ((I64)((point[2]/header.z_scale_factor)/10000000))*10000000*header.z_scale_factor;
// open laswriter
LASwriter* laswriter = laswriteopener.open(&header);
// read and write points
while (lasreader->read_point())
lasreader->point.compute_coordinates();
transform(lasreader->point.coordinates, lasreader->point.coordinates);
// create XYZ quantized with new quantizer
lasreader->point.compute_XYZ(&header);