1 do not clear your Columns: create the Columns once, then copy the structure of the first DataTable to the second:
dataGridView1.DataSource = data1;
data2 = data1.Clone();
dataGridView2.DataSource = data2;
2 get the selected Rows in the first DGV, then update the second DataTable:
IEnumerable<DataGridViewRow> selrows = dataGridView1.Rows.Cast<DataGridViewRow>().Where((DataGridViewRow row) =>
Convert.ToBoolean(row.Cells["colTransfer"].Value));
data2.Rows.Clear();
foreach (DataGridViewRow row in selrows)
{
int ndx = row.Index;
data2.Rows.Add(data1.Rows[ndx].ItemArray);
}
3 I don't see what the problem is with adding additional rows based on searching: get the Index of the new rows, and use the same technique to add them as shown in #2.
Or, maybe, set the CheckBoxes that match the found rows to 'Checked, and then refresh the second DataTable bound to the second DataGridView: clearing the rows, and then using the code in #2,